package src;


import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import javax.swing.BorderFactory;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author JMix
 */
public class JFigura extends JPanel {
    
    private int x;
    private int y;
    private int dragFromX;
    private int dragFromY;
    private int ancho;
    private int alto;
    
    ArrayList<Flecha> flechas;
    private Color color;
    private Ramo ramo;
    Point auxPoint;
    private int tamañoLetra;
    
    public JFigura(int x, int y, String texto, Ramo ramo, int orientacionMalla){
        super.setLayout(new BorderLayout());
        this.x = x;
        this.y = y;
        this.ramo = ramo;
        this.auxPoint = new Point(0, 0);
        color = Color.white;
        super.setBackground(seleccionarColor(ramo.situacionRamo));
        super.setBorder(BorderFactory.createLineBorder(Color.black));
        JLabel label = new JLabel("<html><center>" + "" + "</center></html>", SwingConstants.CENTER);
        label.setFont(new Font("Arial", 0, tamañoLetra));
        super.add(label);
        JLabel label2 = new JLabel( "" );
        super.add( label2, BorderLayout.WEST);
        //super.add(label, BorderLayout.CENTER);
        this.setTexto();
        this.defineTamaño(orientacionMalla);
        super.setBounds(x, y, this.ancho, this.alto);
        this.flechas = new ArrayList<>();
        //super.setToolTipText("hola");        
    }
    
    public JFigura(){
    }
    
    public int getCreditos(){
        return this.ramo.getCreditos();
    }
    
    public Ramo getRamo(){
        return this.ramo;
    }
    
    public boolean inside(Point p){
        if(p.x > this.getX() && p.x < this.getX() + ancho && p.y > this.getY() && p.y < this.getY() + alto)
            return true;
        return false;
    }

    public void setX( int x ) {
        this.x = x;
    }

    public void setY( int y ) {
        this.y = y;
    }
    
    public void changeColor(){
        if(this.color == Color.white){
            this.color = Color.yellow;
        } else {
            this.color = Color.white;
        }
    }
    
    public String getNombre(){
        return this.ramo.getNombre();
    }
    
    public void seleccionar(){
        JPanel p1 = new JPanel();
        p1.setLayout(new BorderLayout());
        p1.setBackground(Color.GREEN);
        p1.setBounds(0, 0, 10, 10);
        super.add(p1, BorderLayout.EAST);
        //updateUI();
    }
    
    /**
     * Entrega nivel o año al que pertenece el ramo asociado a la figura
     * @return nivel al que pertenece el ramo
     */
    public int getNivel(){
        return ramo.getNivel();
    }
    
    public void setRamo(Ramo ramo){
        this.ramo = ramo;
        this.setTexto();
    }

    void setTexto() {
        //System.out.println("---------------texto seteado");
        JLabel l = (JLabel) super.getComponent(0);
        l.setFont(new Font("Arial", 0, tamañoLetra));
        if (ramo.getNombre().length() < 40)
            l.setText("<html><center>" + ramo.nombre + "</center></html>");
        else
            l.setText("<html><center>" + ramo.nombre.substring(0, 39) + "...</center></html>");
        JLabel l2 = (JLabel) super.getComponent(1);
        l2.setFont(new Font("Arial", 0, tamañoLetra));
        String creditos = String.valueOf( ramo.getCreditos() );
        l2.setForeground(Color.gray);
        l2.setText( creditos );
        super.updateUI();
    }
    
    /**
     * Retorna el punto superior izquierdo donde se ubica la figura.
     * @return Point(x,y)
     */
    public Point getPunto()
    {
        return new Point(this.x, this.y);
    }
    
    /**
     * Retorna el centro de la figura.
     * @return Point(x+ancho, y+alto)
     */
    public Point getCentro()
    {
        return new Point( x + ancho/2 , y + alto/2 );
    }

    public int getDragFromX()
    {
        return dragFromX;
    }

    public void setDragFromX(int dragFromX)
    {
        this.dragFromX = dragFromX;
    }

    public int getDragFromY()
    {
        return dragFromY;
    }

    public void setDragFromY(int dragFromY)
    {
        this.dragFromY = dragFromY;
    }

    public int getAlto()
    {
        return alto;
    }

    public void setAlto(int alto)
    {
        this.alto = alto;
    }

    public int getAncho()
    {
        return ancho;
    }

    public void setAncho(int ancho)
    {
        this.ancho = ancho;
    }
    
    //Orientacion 0 es vertical, 1 es horizontal
    public void defineTamaño( int orientacion )
    {
        int vertical = 0;
        int horizontal = 1;
        String p = ramo.getPeriodo();
        if( p.equals( "Anual" ) )
        {
            this.ancho = 150;
            this.alto = 155;
            this.tamañoLetra = 20;
        }
        else if( p.equals("Semestre 1") || p.equals("Semestre 2") )
        {
            if( orientacion == vertical ) //Ancho debe ser igual a espacio
            {
                this.ancho = 150;
                this.alto = 60;
                this.tamañoLetra = 14;
            }
            else if( orientacion == horizontal )
            {
                this.ancho = 60;
                this.alto = 150;
                this.tamañoLetra = 9;
            }
        }
        else if( p.equals("Trimestre 1") || p.equals("Trimestre 2") || p.equals("Trimestre 3") )
        {
            if( orientacion == vertical ) //Ancho debe ser igual a espacio
            {
                this.ancho = 150;
                this.alto = 35;
                this.tamañoLetra = 10;
            }
            else if( orientacion == horizontal )
            {
                this.ancho = 35;
                this.alto = 150;
                this.tamañoLetra = 7;
            }
        }
        this.setTexto();
    }

    public Rectangle getRectangle()
    {
        return new Rectangle(x, y, this.ancho, this.alto);
    }

    /**
     * Agrega una flecha que parte desde esta figura hasta la fig que recibe 
     */
    public void agregarFlecha(JFigura fig, int orientacionPanel) {
        this.flechas.add(new Flecha(this.getPunto(), fig.getPunto(), this.ramo, fig.getRamo(), this.getDimension(), fig.getDimension(), orientacionPanel));
    }
    
    public Dimension getDimension(){
        return new Dimension(this.ancho, this.alto);
    }
    
    void clear() {
        for (Flecha f : flechas){
            f.eliminarInterrupciones();
        }
    }
    
    public void cargarFlecha(Flecha flecha){
        this.flechas.add(flecha);
    }
    public ArrayList<Flecha> getFlechas(){
        return this.flechas;
    }
//    
//     public void pintarFlechasConSaltos(Graphics g){
//        for (Flecha flecha : this.flechas){
//            if (flecha.tieneSaltosHorizontales()){
//                flecha.paint(g);
//            }
//        }
//    }
//    
//    public void pintarFlechasSinSaltos(Graphics g){
//        for (Flecha flecha : this.flechas){
//            if (!flecha.tieneSaltosHorizontales()){
//                flecha.paint(g);
//            }
//        }
//    }

    public Flecha contieneFlecha(Point point) {
        for (Flecha flecha : flechas){
            if (flecha.dentro(point) != null){
                return flecha;
            }
        }
        return null;
    }
    
    public void pintarLineasHorizontales(Graphics g){
        for (Flecha flecha : flechas){
            flecha.pintarLineasHorizontales(g);
        }
    }
    
    public void pintarLineasVerticales(Graphics g){
        for(Flecha flecha : flechas){
            flecha.pintarLineasVerticales(g);
        }
    }

    public boolean contieneFlecha(Flecha flechaPresionada) {
        for (Flecha flecha : flechas){
            if (flecha.equals(flechaPresionada)){
                return true;
            }
        }
        return false;
    }
    
    public ArrayList<Point> dentroFlecha(Point point) {
        for (Flecha flecha : this.flechas){
            if (flecha.dentro(point) != null){
                return flecha.dentro(point);
            }
        }
        return null;
    }

    void setFlechasSalientes(int orientacion) {
        if (orientacion == JPanelDibujo.vertical){
            for (int i=0; i<this.flechas.size(); i++){
                this.flechas.get(i).setInicio(super.getLocation(), orientacion);
            }
        }
        else if (orientacion == JPanelDibujo.horizontal){
            for (int i=0; i<this.flechas.size(); i++){
                this.flechas.get(i).setInicio(super.getY()+this.alto/2);
            }
        }
    }
    
        
    public void setFinalFlecha(Point point, Ramo llegada, int orientacion) {
        for (Flecha flecha : this.flechas){
            if (flecha.llegada().getNombre().equals(llegada.getNombre())){
                flecha.setFinal(point, orientacion);
            }
        }   
    }
    
    void modificarPosicionFlechas(int orientacion) {
        for (Flecha flecha : flechas){
            flecha.modificarPosicionFlechas(orientacion);
        }
    }

//    void pintarFlechasConInterrupciones(Graphics2D g2d) {
//        for (Flecha flecha : flechas){
//            if (flecha.getInterrupciones().size() > 0){
//                flecha.paint(g2d);
//            }
//        }
//    }
//
//    void pintarFlechasSinInterrupciones(Graphics2D g2d) {
//        for (Flecha flecha : flechas){
//            if (flecha.getInterrupciones().size() == 0){
//                flecha.paint(g2d);
//            }
//        }
//    }
//
//    void pintarFlechas(Graphics2D g2d) {
//        for (Flecha flecha : flechas){
//            flecha.paint(g2d);
//        }
//    }

    public void eliminarFlecha(Ramo r) {
        System.out.println("soy la fig " + this.getNombre() + " y debo eliminar flecha a " + r.nombre);
        Flecha aEliminar = null;
        for (Flecha flecha : this.flechas){
            if (flecha.llegada().nombre.equals(r.nombre)){
                aEliminar = flecha;
            }
        }
        this.flechas.remove(aEliminar);
    }

    void eliminarFlechas() {
        while(!this.flechas.isEmpty())
            this.flechas.remove(0);
    }

    boolean tieneFlechaA(Ramo r) {
        for (Flecha f : flechas){
            System.out.println("comparando " + r.getNombre() + " con " + f.llegada().getNombre());
            if (f.llegada().equals(r)){
                System.out.println(this.getNombre() + " SI tiene a " + r.getNombre());
                return true;
            }
        }
        return false;
    }

    void rotarFlechas() {
        for (Flecha f : flechas){
            f.rotar();
        }
    }

    void resaltarFlechas(boolean b) {
        for (Flecha flecha : this.flechas){
            flecha.setResaltar(b);
        }
    }

    void eliminarFlecha(Flecha aux) {
        this.flechas.remove(aux);
    }

    void revisarFlechasRepetidas(){
        Flecha aux = null;
        int count = 0;
        for(Flecha f1 : flechas){
            count = 0;
            for (Flecha f2 : flechas){
                if (f1.llegada().nombre.equals(f2.llegada().nombre)){
                    count++;
                    if (count > 1)
                        aux = f2;
                }
            }
        }
        if (count > 1)
            this.flechas.remove(aux);
        
    }
    void aprobado() {
        this.ramo.setSituacionRamo(SituacionRamo.APROBADO);
        this.setBackground(Color.green);
    }

    void reprobado() {
        this.ramo.setSituacionRamo(SituacionRamo.REPROBADO);
        this.setBackground(Color.red);
    }

    void cursando() {
        this.ramo.setSituacionRamo(SituacionRamo.CURSANDO);
        this.setBackground(Color.yellow);
    }

    void porCursar() {
        this.ramo.setSituacionRamo(SituacionRamo.POR_CURSAR);
        this.setBackground(Color.white);
    }

    private Color seleccionarColor(SituacionRamo situacionRamo) {
        switch(situacionRamo){
            case APROBADO:
                return Color.GREEN;
            case REPROBADO:
                return Color.RED;
            case CURSANDO:
                return Color.YELLOW;
        }
        return Color.white;
    }

    public void pintarPuntas(Graphics2D g2d) {
        for (Flecha flecha : this.flechas){
            flecha.pintarPuntas(g2d);
        }
    }
}
